package user

import (
	"fmt"

	"gitee.com/linxing_3/youye-datatypes/jsonfield"
)

var _ ISessionInfo = (*SessionInfo)(nil)

type SThird map[string]interface {
}

func (s SThird) GetOpenId() (string, bool) {
	id, ok := s["openId"]
	if !ok {
		return "", false
	}
	if idStr, ok := id.(string); ok {
		return idStr, true
	} else {
		return fmt.Sprintf("%v", id), true
	}
}

type SessionInfo struct {
	UserId     string                                       `json:"userId"`     // 用户id
	Username   string                                       `json:"username"`   // 用户账号
	NickName   string                                       `json:"nickName"`   // 用户昵称
	Email      string                                       `json:"email"`      // 用户邮箱
	Phone      string                                       `json:"phone"`      // 用户手机
	TenantId   string                                       `json:"tenantId"`   // 租户id
	RoleId     string                                       `json:"roleId"`     // 角色id
	DeptId     string                                       `json:"deptId"`     // 部门id
	DeptPath   string                                       `json:"deptPath"`   // 部门路径
	HostName   string                                       `json:"hostName"`   // 主机名
	DeviceType string                                       `json:"deviceType"` // 设备类型
	AppKey     string                                       `json:"appKey"`     // 应用key
	SessionId  string                                       `json:"sessionId"`  // 会话id
	Third      *jsonfield.StrJson[map[string]ISessionThird] `json:"third"`      // 第三方登录信息
}

func (s *SessionInfo) initThird() {
	if s.Third == nil {
		val := map[string]ISessionThird{}
		s.Third = jsonfield.NewStrJsonPtr(val)
	}
}

// GetThird implements ISessionInfo.
func (s *SessionInfo) GetThird() map[string]ISessionThird {
	if s.Third == nil {
		return map[string]ISessionThird{}
	}
	return s.Third.Unwrap()
}

// GetThirdPlatform implements ISessionInfo.
func (s *SessionInfo) GetThirdPlatform(platform string) (ISessionThird, bool) {
	third := s.GetThird()
	info, ok := third[platform]
	return info, ok
}

// SetThird implements ISessionInfo.
func (s *SessionInfo) SetThird(platform string, info ISessionThird) error {
	s.initThird()
	s.Third.Unwrap()[platform] = info
	return nil
}

func (s *SessionInfo) GetUserId() string     { return s.UserId }
func (s *SessionInfo) GetAppKey() string     { return s.AppKey }
func (s *SessionInfo) GetHost() string       { return s.HostName }
func (s *SessionInfo) GetDeviceType() string { return s.DeviceType }
func (s *SessionInfo) GetUsername() string   { return s.Username }
func (s *SessionInfo) GetNickName() string   { return s.NickName }
func (s *SessionInfo) GetEmail() string      { return s.Email }
func (s *SessionInfo) GetPhone() string      { return s.Phone }
func (s *SessionInfo) GetTenantId() string   { return s.TenantId }
func (s *SessionInfo) GetRoleId() string     { return s.RoleId }
func (s *SessionInfo) GetDeptId() string     { return s.DeptId }
func (s *SessionInfo) GetDeptPath() string   { return s.DeptPath }
func (s *SessionInfo) GetSessionId() string  { return s.SessionId }

func (s *SessionInfo) GetClaim() map[string]string {
	return map[string]string{
		"userId":    s.UserId,
		"username":  s.Username,
		"nickName":  s.NickName,
		"email":     s.Email,
		"phone":     s.Phone,
		"tenantId":  s.TenantId,
		"roleId":    s.RoleId,
		"deptId":    s.DeptId,
		"deptPath":  s.DeptPath,
		"sessionId": s.SessionId,
		"third":     s.Third.String(),
	}
}
func (s *SessionInfo) LoadFromClaim(val map[string]string) error {
	s.UserId = val["userId"]
	s.Username = val["username"]
	s.NickName = val["nickName"]
	s.Email = val["email"]
	s.Phone = val["phone"]
	s.TenantId = val["tenantId"]
	s.RoleId = val["roleId"]
	s.DeptId = val["deptId"]
	s.DeptPath = val["deptPath"]
	s.SessionId = val["sessionId"]
	if thirdStr, ok := val["third"]; ok {
		s.initThird()
		s.Third.UnmarshalJSON([]byte(thirdStr))
	}
	return nil
}
